home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Name:
- LOAD_MTM.C
-
- Description:
- MTM module loader
-
- Portability:
- All systems - all compilers (hopefully)
-
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "mikmod.h"
-
- /**************************************************************************
- **************************************************************************/
-
-
- typedef struct MTMSAMPLE{
- char samplename[22];
- ULONG length;
- ULONG reppos;
- ULONG repend;
- UBYTE finetune;
- UBYTE volume;
- UBYTE attribute;
- } MTMSAMPLE;
-
-
-
- typedef struct MTMHEADER{
- UBYTE id[3]; /* MTM file marker */
- UBYTE version; /* upper major, lower nibble minor version number */
- char songname[20]; /* ASCIIZ songname */
- UWORD numtracks; /* number of tracks saved */
- UBYTE lastpattern; /* last pattern number saved */
- UBYTE lastorder; /* last order number to play (songlength-1) */
- UWORD commentsize; /* length of comment field */
- UBYTE numsamples; /* number of samples saved */
- UBYTE attribute; /* attribute byte (unused) */
- UBYTE beatspertrack; /* */
- UBYTE numchannels; /* number of channels used */
- UBYTE panpos[32]; /* voice pan positions */
- } MTMHEADER;
-
-
- typedef struct MTMNOTE{
- UBYTE a,b,c;
- } MTMNOTE;
-
-
- /**************************************************************************
- **************************************************************************/
-
-
-
- static MTMHEADER *mh;
- MTMNOTE *mtmtrk;
- UWORD pat[32];
-
- char MTM_Version[]="MTM";
-
-
-
- BOOL MTM_Test(void)
- {
- char id[3];
- if(!fread(id,3,1,modfp)) return 0;
- if(!memcmp(id,"MTM",3)) return 1;
- return 0;
- }
-
-
- BOOL MTM_Init(void)
- {
- mtmtrk=NULL;
- mh=NULL;
-
- if(!(mtmtrk=(MTMNOTE *)MyCalloc(64,sizeof(MTMNOTE)))) return 0;
- if(!(mh=(MTMHEADER *)MyCalloc(1,sizeof(MTMHEADER)))) return 0;
-
- return 1;
- }
-
-
- void MTM_Cleanup(void)
- {
- if(mtmtrk!=NULL) free(mtmtrk);
- if(mh!=NULL) free(mh);
- }
-
-
-
- UBYTE *MTM_Convert(void)
- {
- int t;
- UBYTE a,b,c,inst,note,eff,dat;
-
- UniReset();
- for(t=0;t<64;t++){
-
- a=mtmtrk[t].a;
- b=mtmtrk[t].b;
- c=mtmtrk[t].c;
-
- inst=((a&0x3)<<4)|(b>>4);
- note=a>>2;
-
- eff=b&0xf;
- dat=c;
-
-
- if(inst!=0){
- UniInstrument(inst-1);
- }
-
- if(note!=0){
- UniNote(note+24);
- }
-
- /* mtm bug bugfix: when the effect is volslide,
- slide-up _always_ overrides slide-dn. */
-
- if(eff==0xa && dat&0xf0) dat&=0xf0;
-
- UniPTEffect(eff,dat);
- UniNewline();
- }
- return UniDup();
- }
-
-
- BOOL MTM_Load(void)
- {
- MTMSAMPLE s;
- INSTRUMENT *d;
- SAMPLE *q;
-
- int t,u;
-
- /* try to read module header */
-
- _mm_read_UBYTES(mh->id,3,modfp);
- mh->version =_mm_read_UBYTE(modfp);
- _mm_read_str(mh->songname,20,modfp);
- mh->numtracks =_mm_read_I_UWORD(modfp);
- mh->lastpattern =_mm_read_UBYTE(modfp);
- mh->lastorder =_mm_read_UBYTE(modfp);
- mh->commentsize =_mm_read_I_UWORD(modfp);
- mh->numsamples =_mm_read_UBYTE(modfp);
- mh->attribute =_mm_read_UBYTE(modfp);
- mh->beatspertrack=_mm_read_UBYTE(modfp);
- mh->numchannels =_mm_read_UBYTE(modfp);
- _mm_read_UBYTES(mh->panpos,32,modfp);
-
- if(feof(modfp)){
- myerr=ERROR_LOADING_HEADER;
- return 0;
- }
-
- /* set module variables */
-
- of.initspeed=6;
- of.inittempo=125;
- of.modtype=strdup(MTM_Version);
- of.numchn=mh->numchannels;
- of.numtrk=mh->numtracks+1; /* get number of channels */
- of.songname=DupStr(mh->songname,20); /* make a cstr of songname */
- of.numpos=mh->lastorder+1; /* copy the songlength */
- of.numpat=mh->lastpattern+1;
- for(t=0;t<32;t++) of.panning[t]=mh->panpos[t]<<4;
-
- of.numins=mh->numsamples;
- if(!AllocInstruments()) return 0;
-
- d=of.instruments;
-
- for(t=0;t<of.numins;t++){
-
- d->numsmp=1;
- if(!AllocSamples(d)) return 0;
- q=d->samples;
-
- /* try to read sample info */
-
- _mm_read_str(s.samplename,22,modfp);
- s.length =_mm_read_I_ULONG(modfp);
- s.reppos =_mm_read_I_ULONG(modfp);
- s.repend =_mm_read_I_ULONG(modfp);
- s.finetune =_mm_read_UBYTE(modfp);
- s.volume =_mm_read_UBYTE(modfp);
- s.attribute =_mm_read_UBYTE(modfp);
-
- if(feof(modfp)){
- myerr=ERROR_LOADING_SAMPLEINFO;
- return 0;
- }
-
- d->insname=DupStr(s.samplename,22);
- q->seekpos=0;
- q->c2spd=finetune[s.finetune];
- q->length=s.length;
- q->loopstart=s.reppos;
- q->loopend=s.repend;
- q->volume=s.volume;
-
- q->flags=0;
-
- if(s.repend-s.reppos>2) q->flags|=SF_LOOP; /* <- 1.00 bugfix */
-
- if(s.attribute&1){
-
- /* If the sample is 16-bits, convert the length
- and replen byte-values into sample-values */
-
- q->flags|=SF_16BITS;
- q->length>>=1;
- q->loopstart>>=1;
- q->loopend>>=1;
- }
-
- d++;
- }
-
- _mm_read_UBYTES(of.positions,128,modfp);
-
- if(feof(modfp)){
- myerr=ERROR_LOADING_HEADER;
- return 0;
- }
-
- if(!AllocTracks()) return 0;
- if(!AllocPatterns()) return 0;
-
- of.tracks[0]=MTM_Convert(); /* track 0 is empty */
-
- for(t=1;t<of.numtrk;t++){
- int s;
-
- for(s=0;s<64;s++){
- mtmtrk[s].a=_mm_read_UBYTE(modfp);
- mtmtrk[s].b=_mm_read_UBYTE(modfp);
- mtmtrk[s].c=_mm_read_UBYTE(modfp);
- }
-
- if(feof(modfp)){
- myerr="Error loading track";
- return 0;
- }
-
- if(!(of.tracks[t]=MTM_Convert())) return 0;
- }
-
- for(t=0;t<of.numpat;t++){
-
- _mm_read_I_UWORDS(pat,32,modfp);
-
- for(u=0;u<of.numchn;u++){
- of.patterns[((long)t*of.numchn)+u]=pat[u];
- }
- }
-
- /* read comment field */
-
- if(!ReadComment(mh->commentsize)) return 0;
-
- return 1;
- }
-
-
-
- LOADER load_mtm={
- NULL,
- "MTM",
- "Portable MTM loader v0.1",
- MTM_Init,
- MTM_Test,
- MTM_Load,
- MTM_Cleanup
- };
-
-